激活函数

Pasted image 20240607103854.png

好的,以下是对常见的四种激活函数的详细对比分析及其使用场景: Pasted image 20240607150028.png

1. Sigmoid 激活函数

特点

  • 输出范围在 (0, 1) 之间。
  • 非线性,能够对输入进行非线性变换。
  • 常用于二分类问题的输出层。

优点

  • 平滑且连续,适合概率输出。
  • 对小输入值有较强的响应。

缺点

  • 梯度消失问题,特别是当输入值较大或较小时。
  • 输出不以 0 为中心,这可能导致训练收敛缓慢。

使用场景

  • 二分类问题的输出层,例如逻辑回归或二分类神经网络。

2. Tanh (双曲正切) 激活函数

特点

  • 输出范围在 (-1, 1) 之间。
  • 非线性,能够对输入进行非线性变换。

优点

  • 输出以 0 为中心,适合于零均值的输入数据。
  • 相比 Sigmoid 函数,梯度消失问题有所缓解。

缺点

  • 仍然可能存在梯度消失问题,但较 Sigmoid 函数有所改善。

使用场景

  • 适用于隐藏层,尤其在有序数据(如时间序列)中较为常见。

3. ReLU (Rectified Linear Unit) 激活函数

特点

  • 输出范围在 [0, ∞) 之间。
  • 非线性,但在正区间是线性的。

优点

  • 避免了梯度消失问题。
  • 在正区间保持梯度,使得训练更快。
  • 计算效率高,简化了反向传播过程。

缺点

  • 可能出现“神经元死亡”问题,即输入为负时梯度为零,导致神经元不更新。
  • 输出不以 0 为中心。

使用场景

  • 深度神经网络中的隐藏层,尤其是卷积神经网络(CNN)。

4. Leaky ReLU 激活函数

其中 是一个小于 1 的常数(例如 0.01)。

特点

  • 类似 ReLU,但允许负斜率。

优点

  • 避免了 ReLU 的“神经元死亡”问题。
  • 在负区间仍有梯度,保持神经元的活跃性。

缺点

  • 仍然不是以 0 为中心输出。

使用场景

  • 深度神经网络中的隐藏层,解决了 ReLU 的缺陷。

激活函数对比

激活函数 输出范围 是否有梯度消失 输出中心 计算效率 常见应用
Sigmoid (0, 1) 非零 二分类输出层
Tanh (-1, 1) 有,但较少 隐藏层,时间序列
ReLU [0, ∞) 非零 隐藏层,卷积神经网络
Leaky ReLU (-∞, ∞) 非零 隐藏层,解决 ReLU 缺陷

使用场景

  1. Sigmoid

    • 用于二分类问题的输出层,因为其输出可以解释为概率。
  2. Tanh

    • 适用于有序数据或需要对称激活函数的隐藏层。
    • 通常在 RNN 中应用较多。
  3. ReLU

    • 广泛应用于各种深度神经网络的隐藏层,特别是卷积神经网络(CNN)。
    • 优点在于其计算效率和梯度问题上的优势。
  4. Leaky ReLU

    • 用于解决 ReLU 的“神经元死亡”问题,广泛应用于深度神经网络的隐藏层。

通过合理选择激活函数,可以显著提高神经网络的训练效率和性能,针对不同任务和网络架构选择合适的激活函数是模型设计中的重要一步。

import numpy as np
import matplotlib.pyplot as plt
import sympy as sp

# 定义变量
x = sp.symbols('x')

# 定义激活函数
sigmoid = 1 / (1 + sp.exp(-x))
tanh = sp.tanh(x)
relu = sp.Piecewise((0, x < 0), (x, x >= 0))
leaky_relu = sp.Piecewise((0.01*x, x < 0), (x, x >= 0))

# 转换为可计算的函数
sigmoid_func = sp.lambdify(x, sigmoid, 'numpy')
tanh_func = sp.lambdify(x, tanh, 'numpy')
relu_func = sp.lambdify(x, relu, 'numpy')
leaky_relu_func = sp.lambdify(x, leaky_relu, 'numpy')

# 定义x的范围
x_vals = np.linspace(-10, 10, 400)

# 计算激活函数的值
sigmoid_vals = sigmoid_func(x_vals)
tanh_vals = tanh_func(x_vals)
relu_vals = relu_func(x_vals)
leaky_relu_vals = leaky_relu_func(x_vals)

# 创建图形
plt.figure(figsize=(10, 8))

plt.subplot(2, 2, 1)
plt.plot(x_vals, sigmoid_vals, label='Sigmoid')
plt.title('Sigmoid Activation Function')
plt.xlabel('x')
plt.ylabel('σ(x)')
plt.grid(True)
plt.legend()

plt.subplot(2, 2, 2)
plt.plot(x_vals, tanh_vals, label='Tanh', color='orange')
plt.title('Tanh Activation Function')
plt.xlabel('x')
plt.ylabel('tanh(x)')
plt.grid(True)
plt.legend()

plt.subplot(2, 2, 3)
plt.plot(x_vals, relu_vals, label='ReLU', color='green')
plt.title('ReLU Activation Function')
plt.xlabel('x')
plt.ylabel('ReLU(x)')
plt.grid(True)
plt.legend()

plt.subplot(2, 2, 4)
plt.plot(x_vals, leaky_relu_vals, label='Leaky ReLU', color='red')
plt.title('Leaky ReLU Activation Function')
plt.xlabel('x')
plt.ylabel('Leaky ReLU(x)')
plt.grid(True)
plt.legend()

plt.tight_layout()
plt.show()